import { Injectable, Inject, forwardRef } from '@nestjs/common';
import { SocketGateway } from '@/modules/socket/socket.gateway';
import { FileSystemEntry } from '../virtual-file-system/types';

/**
 * 文件系统变更事件类型
 */
export type VFSEventType = 'create' | 'update' | 'delete' | 'rename';

/**
 * 文件系统变更事件
 */
export interface VFSChangeEvent {
  type: VFSEventType;
  projectId: string;
  path: string;
  entry?: FileSystemEntry;
  oldPath?: string; // 用于 rename 事件
  userId?: number;
  timestamp: number;
}

/**
 * VFS 事件服务
 * 负责向前端推送文件系统变更事件
 */
@Injectable()
export class VFSEventService {
  constructor(
    @Inject(forwardRef(() => SocketGateway))
    private socketGateway: SocketGateway,
  ) {}

  /**
   * 发送文件创建事件
   */
  async emitFileCreated(
    projectId: string,
    path: string,
    entry: FileSystemEntry,
    userId?: number,
  ): Promise<void> {
    const event: VFSChangeEvent = {
      type: 'create',
      projectId,
      path,
      entry,
      userId,
      timestamp: Date.now(),
    };

    this.broadcastToProject(projectId, 'vfs:change', event);
  }

  /**
   * 发送文件更新事件
   */
  async emitFileUpdated(
    projectId: string,
    path: string,
    entry: FileSystemEntry,
    userId?: number,
  ): Promise<void> {
    const event: VFSChangeEvent = {
      type: 'update',
      projectId,
      path,
      entry,
      userId,
      timestamp: Date.now(),
    };

    this.broadcastToProject(projectId, 'vfs:change', event);
  }

  /**
   * 发送文件删除事件
   */
  async emitFileDeleted(
    projectId: string,
    path: string,
    userId?: number,
  ): Promise<void> {
    const event: VFSChangeEvent = {
      type: 'delete',
      projectId,
      path,
      userId,
      timestamp: Date.now(),
    };

    this.broadcastToProject(projectId, 'vfs:change', event);
  }

  /**
   * 发送文件重命名事件
   */
  async emitFileRenamed(
    projectId: string,
    oldPath: string,
    newPath: string,
    entry: FileSystemEntry,
    userId?: number,
  ): Promise<void> {
    const event: VFSChangeEvent = {
      type: 'rename',
      projectId,
      path: newPath,
      oldPath,
      entry,
      userId,
      timestamp: Date.now(),
    };

    this.broadcastToProject(projectId, 'vfs:change', event);
  }

  /**
   * 向项目房间广播消息
   */
  private broadcastToProject(
    projectId: string,
    eventName: string,
    data: any,
  ): void {
    if (this.socketGateway && this.socketGateway.server) {
      // 向项目房间广播
      this.socketGateway.server.to(projectId).emit(eventName, data);
      console.log(`[VFS Event] 广播到项目 ${projectId}:`, eventName, data);
    }
  }

  /**
   * 批量发送文件变更事件
   */
  async emitBatchChanges(
    projectId: string,
    events: VFSChangeEvent[],
  ): Promise<void> {
    if (this.socketGateway && this.socketGateway.server) {
      this.socketGateway.server.to(projectId).emit('vfs:batch-change', {
        projectId,
        events,
        timestamp: Date.now(),
      });
    }
  }
}

